package org.folio.rest.impl;

import cn.hutool.core.util.StrUtil;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import org.folio.rest.impl.other.PartyLogSave;
import org.folio.rest.impl.other.notify.INotify;
import org.folio.rest.impl.other.notify.impl.INotifyImpl;
import org.folio.rest.impl.util.ParallelAsyncTaskExecutor;
import org.folio.rest.jaxrs.model.NotifyLog;
import org.folio.rest.jaxrs.model.ReaderReserveGroup;
import org.folio.rest.jaxrs.model.ReserveGroup;
import org.folio.rest.jaxrs.model.UrgentNotify;
import org.folio.rest.jaxrs.resource.PartyUrgentNotify;
import org.folio.rest.persist.PgUtil;
import org.folio.rest.persist.PostgresClient;

import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

public class UrgentNotifyImpl implements PartyUrgentNotify {


    @Override
    public void postPartyUrgentNotify(String lang, UrgentNotify entity, Map<String, String> okapiHeaders,
                                      Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        entity.setSendStatus(true);
        if (entity.getReserveGroup() == null || entity.getReserveGroup().size() == 0) {
            entity.setSendStatus(false);
            entity.setMessage("发送短信通知失败！本次共成功发送：" + 0 + "条，发送失败：" + 0 + "条");
            asyncResultHandler.handle(Future.succeededFuture(PostPartyUrgentNotifyResponse.respond201WithApplicationJson(entity, PostPartyUrgentNotifyResponse.headersFor201())));
            return;
        }
        final List<ReserveGroup> reserveList = entity.getReserveGroup();
        //过滤
        Map<Boolean, List<ReserveGroup>> mobilePhoneIsBlankMap =
                reserveList.stream().collect(Collectors.partitioningBy((a) -> a.getReaderReserveGroup().size() == 0
                        || a.getReaderReserveGroup().get(0) == null
                        || StrUtil.isBlankOrUndefined(a.getReaderReserveGroup().get(0).getMobilePhone())
                        || StrUtil.isBlankOrUndefined(a.getId())));

        //缺乏联系人信息
        List<ReserveGroup> noNotifyUserList = mobilePhoneIsBlankMap.get(true);
        List<ReserveGroup> waitNotifyUserList = mobilePhoneIsBlankMap.get(false);
        if (waitNotifyUserList.size() == 0) {
            entity.setSendStatus(false);
            entity.setMessage("发送短信通知失败！本次共成功发送：" + 0 + "条，发送失败：" + noNotifyUserList.size() + "条");
            asyncResultHandler.handle(Future.succeededFuture(PostPartyUrgentNotifyResponse.respond201WithApplicationJson(entity, PostPartyUrgentNotifyResponse.headersFor201())));
            return;
        }
        ParallelAsyncTaskExecutor executor = new ParallelAsyncTaskExecutor();
        Map<String, ReserveGroup> sendObjectMap = new HashMap<>();
        waitNotifyUserList.forEach(reserve -> {
            ReaderReserveGroup readerReserveGroup = reserve.getReaderReserveGroup().get(0);
            INotifyImpl notify = INotify.create(okapiHeaders, vertxContext, "2", "");
            sendObjectMap.put(reserve.getId(), reserve);
            executor.addAsyncTask(notify.sendSms(reserve.getId(), readerReserveGroup.getMobilePhone(), entity.getMessage()));
        });
        executor.start();
        executor.setHandler(
                res -> {
                    List<NotifyLog> notifyLogList = (List<NotifyLog>) res.result();

                    Map<Boolean, List<NotifyLog>> notifyLogGroup =
                            notifyLogList.stream().collect(Collectors.partitioningBy(NotifyLog::getSendStatus));
                    int errLen = notifyLogGroup.get(false).size() + noNotifyUserList.size();
                    int successLen = notifyLogGroup.get(true).size();

                    notifyLogList.forEach(
                            a -> {
                                if (!StrUtil.isBlankOrUndefined(a.getId()) && sendObjectMap.get(a.getId()) != null) {
                                    ReserveGroup reserve = sendObjectMap.get(a.getId());
                                    ReaderReserveGroup reader = reserve.getReaderReserveGroup().get(0);
                                    a.setId(UUID.randomUUID().toString());
                                    a.setMetadata(entity.getMetadata());
                                    a.setName(reader.getName());
                                    a.setPhoneNumber(reader.getMobilePhone());
                                    a.setReserveChannel(reserve.getChannel().toString());
                                    a.setPartyName(reserve.getPartyName());
                                    a.setUserAccount(reader.getBarcode());
                                    a.setMessageType("5");
                                    a.setAccountType("1");
                                }
                            });
                    PostgresClient pg = PgUtil.postgresClient(vertxContext, okapiHeaders);
                    pg.saveBatch(
                            "notify_log",
                            notifyLogList,
                            saveReply -> {
                                String message = entity.getMessage();
                                entity.setMessage("发送短信通知成功！本次共成功通知：" + successLen + "条，通知失败：" + errLen + "条");
                                asyncResultHandler.handle(
                                        Future.succeededFuture(
                                                PostPartyUrgentNotifyResponse.respond201WithApplicationJson(
                                                        entity, PostPartyUrgentNotifyResponse.headersFor201())));
                                PartyLogSave.saveLog("发送了内容为【" + message + "】紧急通知", 3, entity.getMetadata(), entity.getOperator(), okapiHeaders, asyncResultHandler, pg);

                            });
                });


    }
}
